import os
import sys
import re
import shutil
import os.path
from shutil import copyfile

root = os.path.split(os.path.realpath(__file__))[0]
root = os.path.dirname(root)

cocos_root = ""
if len(sys.argv) == 2:
    cocos_root = "%s/src" % sys.argv[1]

cocos_proto_root = "%s/assets/resources/proto" % cocos_root
cocos_script_root = "%s/assets/scripts" % cocos_root

# print(root)
shellroot = root + "/shell"
protoroot = root + "/src/pb/proto"
# jsProtoMsgRoot = root + "/bin/client/msg/MsgProto.js"
# jsProtoRoot = root + "/../ws_cocos_client/assets/resources/proto"
# jsRoot = root + "/../ws_cocos_client/assets/scripts"
# shell

os.system('protoc --go_out=import_path=pb:%s/src/core/rpc -I=%s/src/core/rpc %s/src/core/rpc/*.proto' % (
    root, root, root))
os.system('protoc --go_out=import_path=pb:%s/src/pb -I=%s/src/pb/proto %s/src/pb/proto/*.proto' % (
    root, root, root))
# tag
for _, _, files in os.walk(root + "/src/pb"):
    for file in files:
        if '.pb.go' in file:
            os.system('protoc-go-inject-tag -input=%s/src/pb/%s' % (root, file))
# copy common
for parent, dirs, files in os.walk(protoroot):
    for file in files:
        oldfile = '%s/%s' % (protoroot, os.path.basename(file))
        newfile = '%s/bin/client/pb/' % root + os.path.basename(file)
        print("copy %s" % oldfile)
        copyfile(oldfile, newfile)

rpc_files = []
file_list = []
msg_list = []
rpc_list = []
pbmsg_list = []
pbmsg_file_list = {}


def LoadProto():
    for path, dirs, files in os.walk(protoroot):
        for file in files:
            if file.endswith('.proto'):
                if file.find('rpc') != -1:
                    file = os.path.join(path, file)
                    rpc_files.append(file)
                else:
                    file = os.path.join(path, file)
                    file_list.append(file)

    for file in iter(file_list):
        # copyfile(fn,jsProtoRoot+fn[fn.rfind("/"):])
        print("copy file " + file)
        with open(file, "rb") as file_open:
            file_name = "./pb/%s" % os.path.basename(file)
            pbmsg_file_list[file_name] = []
            for i, line in enumerate(file_open.readlines()):
                if line.find("message") != -1:
                    msg = line.split()[1]
                    if msg.find("_") != -1:
                        msg_list.append(msg)
                        pbmsg_list.append(msg)
                        pbmsg_file_list[file_name].append(msg)

    for file in iter(rpc_files):
        with open(file, "rb") as file_open:
            for i, line in enumerate(file_open.readlines()):
                if line.find("message") != -1:
                    msg = line.split()[1]
                    if msg.find("_") != -1:
                        rpc_list.append(msg)


def CreateInitGo():
    with open(root + "/src/pb/init.go", "wb") as codeFile:
        codeStr = "package pb\n\n"
        codeStr = codeStr + "import (\n \"reflect\"\n \"leaf/core/msg\"\n)\n\n"

        codeStr = codeStr + "var MapId2MessageType = map[uint16]reflect.Type{\n"
        for i, msg in enumerate(msg_list):
            codeStr = codeStr + "\t" + str(i + 1 + 100) + ":  reflect.TypeOf(&" + msg + "{}),\n"
        for i, msg in enumerate(rpc_list):
            codeStr = codeStr + "\t" + str(i + 1 + 10000) + ":  reflect.TypeOf(&" + msg + "{}),\n"
        codeStr = codeStr + "}\n"

        codeStr = codeStr + '\nfunc init() {\n\tmsg.RegisterMessage(MapId2MessageType)\n}'

        codeFile.write(codeStr)
        codeFile.close()


def CreatePbJS():
    with open(root + "/bin/client/pb/pb.js", "wb") as codeFile:
        codeStr = '''var pb = {}
var loading =  {}
pb.id2msg = {}
pb.msg2id = {}
pb.proto = {}

function ProtoLoaded() {
	for (var key in loading) {
		return false
	}
	return true
	// console.log("loading.length:",Object.getOwnPropertyNames(loading).length)
	// return loading.length == 0
}

function Register(msg,id) {
    if (pb.msg2id[msg] != null) {
        console.log("register message msg = %s is registed",msg)
    }

    if (pb.id2msg[id] != null) {
        console.log("register message id = %d is registed",id)
    }
    pb.msg2id[msg] = id
    pb.id2msg[id] = msg
	loading[msg] = 1
}

function RegisterProto(msg,root) {
    pb.proto[msg] = root.lookup("pb."+msg);
    if (pb.proto[msg] == null) {
        console.log("proto load " + msg + " error")
    }else{
		delete loading[msg]
	}
}

'''
        for k, v in enumerate(pbmsg_list):
            codeStr = codeStr + "Register(\"" + v + "\"," + str(k + 1 + 100) + ");\n"
        codeStr = codeStr + "\n"
        codeStr = codeStr + "\n"

        for k in pbmsg_file_list.keys():
            codeStr = codeStr + "protobuf.load(\"" + k + "\", function(err,root) { \n if (err) throw err;\n"
            for k, v in enumerate(pbmsg_file_list[k]):
                codeStr = codeStr + "\tRegisterProto(\"" + v + "\",root);\n"
            codeStr = codeStr + "});\n"
        codeStr = codeStr + "\n"

        codeStr = codeStr + "\nexport {pb,ProtoLoaded}"

        codeFile.write(codeStr)
        codeFile.close()


#
# def CreateJSMsgProto():
#     with open(root+"/bin/client/msg/MsgProto.js","wb") as codeFile:
#         codeStr = "var CONST = cc;\n\n"
#         codeStr = codeStr + "CONST.MSG = {\n"
#         msgdic = {}
#         for k,v in enumerate(jsMsgList):
#             code = k+101
#             codeStr = codeStr + "\t"+ jsMsgList[k].upper() + " : " + str(code) + ",\n"
#             msgdic[jsMsgList[k]] = code
#         codeStr = codeStr + "}\n\n"
#
#         codeStr = codeStr + "CONST.PROTO = {};\n"
#         for k in jsFileMsgList.keys():
#            fname = k[k.rfind("/")+1:]
#            fname = fname[:fname.find(".")]
#            codeStr = codeStr + "CONST.PROTO[\"" + fname + "\"] = {\n"
#            for _,msgName in enumerate(jsFileMsgList[k]):
#                 codeStr = codeStr + "\t[CONST.MSG." + msgName.upper() + "] : \"" + msgName + "\",\n"
#            codeStr = codeStr + "}\n\n"
#
#         codeFile.write(codeStr)
#         codeFile.close()
#
#     print(jsProtoMsgRoot)
#     print(jsRoot+jsProtoMsgRoot[jsProtoMsgRoot.rfind("/"):])
#     copyfile(jsProtoMsgRoot,jsRoot+jsProtoMsgRoot[jsProtoMsgRoot.rfind("/"):])


LoadProto()
CreateInitGo()
CreatePbJS()
# CreateJSMsgProto()
